package com.jimmy.medical.service.impl;

import com.jimmy.medical.base.impl.JpaSpecificationServiceImpl;
import com.jimmy.medical.common.StringUtils;
import com.jimmy.medical.entity.*;
import com.jimmy.medical.entity.Order;
import com.jimmy.medical.enums.OrderStatusEnum;
import com.jimmy.medical.model.OrderQueryParam;
import com.jimmy.medical.repository.OrderRepository;
import com.jimmy.medical.service.IFlowOrderService;
import com.jimmy.medical.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.util.ArrayList;

@Service
public class OrderServiceImpl extends JpaSpecificationServiceImpl<OrderRepository, OrderRepository, Order, Long>
        implements IOrderService {

    @Autowired
    @Qualifier("flowOrderService")
    private IFlowOrderService flowOrderService;

    @Override
    public Page<Order> findAll(Pageable pageable, final OrderQueryParam queryParam) {
        return this.findAll(new Specification<Order>() {
            @Override
            public Predicate toPredicate(Root<Order> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
            Join<Order, Member> memberJoin   = root.join("member", JoinType.LEFT);
//            Join<Member, MemberContract> mcJoin = memberJoin.join("member", JoinType.RIGHT);
//            Join<MemberContract, Contract> contractJoin = mcJoin.join("contract", JoinType.LEFT);
//            Join<Contract, MemberType> memberTypeJoin = contractJoin.join("memberType", JoinType.LEFT);


            Join<Member, MemberType> memberTypeJoin = memberJoin.join("memberType", JoinType.LEFT);
            Join<Order, ServiceItem> serviceItemJoin = root.join("serviceItem", JoinType.LEFT);
            Join<Order, Hospital> hospitalJoin = root.join("hospital", JoinType.LEFT);
            Join<Member, User> userJoin = memberJoin.join("user", JoinType.LEFT);

            Path<String> createTimePath = root.get("createTime");
            Path<String> sexPath = memberJoin.get("sex");
            Path<Long> memberTypePath = memberTypeJoin.get("id");
            Path<Long> serviceItemPath = serviceItemJoin.get("id");
            Path<Long> hospitalPath = hospitalJoin.get("id");
            Path<String> statusPath = root.get("status");
            Path<String> signStatusPath = root.get("signStatus");
            Path<String> memberNamePath = memberJoin.get("realname");
            Path<String> memberMobilePath = memberJoin.get("mobile");
            Path<String> userNamePath = userJoin.get("realname");
            Path<String> memberCreateUserPath = memberJoin.get("createUser");  //签单人
            Path<String> memberIdCardPath = memberJoin.get("idCard");


            ArrayList<Predicate> list = new ArrayList<Predicate>();
            if(StringUtils.isNotBlank(queryParam.getStatus())) {
                list.add(criteriaBuilder.equal(statusPath, queryParam.getStatus()));
            } else {
                list.add(criteriaBuilder.notEqual(statusPath, OrderStatusEnum.CANCELED.getKey() + ""));
            }

            if (StringUtils.isNotBlank(queryParam.getStartTime())) {
                list.add(criteriaBuilder.and(criteriaBuilder.greaterThanOrEqualTo(createTimePath, queryParam.getStartTime())));
            }

            if (StringUtils.isNotBlank(queryParam.getEndTime())) {
                list.add(criteriaBuilder.and(criteriaBuilder.lessThanOrEqualTo(createTimePath, queryParam.getEndTime())));
            }

            if (StringUtils.isNotBlank(queryParam.getCreateUser())) {
                list.add(criteriaBuilder.and(criteriaBuilder.like(memberCreateUserPath, queryParam.getCreateUser() + "%")));
            }

            if (StringUtils.isNotBlank(queryParam.getDoctor())) {
                list.add(criteriaBuilder.and(criteriaBuilder.like(userNamePath, queryParam.getDoctor() + "%")));
            }

            if (StringUtils.isNotBlank(queryParam.getIdCard())) {
                list.add(criteriaBuilder.and(criteriaBuilder.like(memberIdCardPath, queryParam.getIdCard() + "%")));
            }

            if (StringUtils.isNotBlank(queryParam.getMobile())) {
                list.add(criteriaBuilder.and(criteriaBuilder.like(memberMobilePath, queryParam.getMobile() + "%")));
            }

            if (StringUtils.isNotBlank(queryParam.getMemberName())) {
                list.add(criteriaBuilder.and(criteriaBuilder.like(memberNamePath, queryParam.getMemberName() + "%")));
            }

            if (StringUtils.isNotBlank(queryParam.getSex())) {
                list.add(criteriaBuilder.and(criteriaBuilder.equal(sexPath, queryParam.getSex())));
            }

            if (StringUtils.isNotBlank(queryParam.getSignStatus())) {
                list.add(criteriaBuilder.and(criteriaBuilder.equal(signStatusPath, queryParam.getSignStatus())));
            }

            if (queryParam.getHospital() != null) {
                list.add(criteriaBuilder.and(criteriaBuilder.equal(hospitalPath, queryParam.getHospital())));
            }

            if (queryParam.getMemberTypeId() != null) {
                list.add(criteriaBuilder.and(criteriaBuilder.equal(memberTypePath, queryParam.getMemberTypeId())));
            }

            if (queryParam.getServiceItemId() != null) {
                list.add(criteriaBuilder.and(criteriaBuilder.equal(serviceItemPath, queryParam.getServiceItemId())));
            }

            return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        }, pageable);
    }

    @Override
    public Long saveCancelMessageFlow(Message message) {
        FlowOrder flowOrder = flowOrderService.process(message.getFlowOrderId(), message.getUserId(), "短信通知退号成功", 2);
        return flowOrderService.getCountDown(flowOrder);
    }

    @Override
    public FlowOrder submitCancel(Long flowOrderId, Long userId) {
        FlowOrder flowOrder = flowOrderService.process(flowOrderId, userId, "完成退号", 3);
        return flowOrderService.getNextFlowOrder(flowOrder);
    }

    @Override
    public Long saveResignNoticeInfo(PhoneCall call) {
        FlowOrder flowOrder = flowOrderService.process(call.getOrderId(), call.getUserId(), "电话通知改号成功", 2);
        return flowOrderService.getCountDown(flowOrder);
    }

    @Override
    public Long saveReSignMessageFlow(Message message) {
        FlowOrder flowOrder = flowOrderService.process(message.getFlowOrderId(), message.getUserId(), "短信通知改号成功", 3);
        return flowOrderService.getCountDown(flowOrder);
    }

    @Override
    public FlowOrder submitReSign(Long flowOrderId, Long userId) {
        FlowOrder flowOrder = flowOrderService.process(flowOrderId, userId, "完成改号", 4);
        return flowOrderService.getNextFlowOrder(flowOrder);
    }
}